<?php

declare(strict_types=1);

namespace Service\WebSocketService;

use Service\BaseService;
use Service\Code\Normal;
use Service\ExportService\ExportExcelHandle;
use App\Model\BbcModel\Goods;
use App\Model\BbcModel\GoodsClass;
use App\Model\BbcModel\GoodsManagerTags;
use App\Model\BbcModel\Storage;
use App\Model\BbcModel\ConfigChannel;
use App\Model\BbcModel\GoodsBrand;
use App\Model\BbcModel\Goodscommon;
use App\Model\BbcModel\GoodsSupplyClass;
use App\Model\BbcModel\GoodsService;
use App\Model\BbcModel\TransitTemplate;
use App\Model\BbcModel\GoodsSpecPrice;
use App\Model\BbcModel\GoodsBatch;
use App\Model\BbcModel\DistributorPrice;
use App\Model\BbcModel\DistributorLevel;
use App\Model\BbcModel\Country;
use App\Model\BbcModel\Mnuser;
use App\Model\BbcModel\MnStoreGoods;
use App\Model\BbcModel\CashGoodsChange;
use App\Model\BbcModel\GoodsLog;
use App\Model\BbcModel\GoodsTags;
use App\Model\BbcModel\GoodsImportLog;
use App\Model\BbcModel\ManagerChannel;
use Service\CommodityService\ChannelCommodityService;
use Service\CommodityService\ChannelCommodityEsService;
use Hyperf\DbConnection\Db;

/**
 * 渠道商品-代发商品资料导入修改
 * @author huj
 */
class ChannelCommodityPriceEditService extends BaseService {

    const CHUNK_NUM = 50;

    /**
     * 代发商品价格导入修改
     * @param object $server
     * @param int $fd
     * @param array $body
     * @param int $manager_id
     * @param int $cid
     * 推送前端客户端方式
     * Normal::returnCode(Normal::WS_START,"开始处理");
     * Normal::returnCode(Normal::WS_END,"处理完成");
     * Normal::returnCode(Normal::WS_ERROR,"处理异常");
     * $server->push($fd,json_encode($result,JSON_UNESCAPED_UNICODE));
     */
    public function batchUpdate($server, int $fd, array $body, int $manager_id, int $cid) {
        ini_set('memory_limit', '3096M');
        // $body = [
        //     'isUploadFile' => 1,
        //     'fileUrl'      => "https://indoorbuydev.oss-cn-hangzhou.aliyuncs.com/sbbc/channel/upload/修改代发商品资料模板_2023081016135035861.xlsx",
        //     'upLoadData'   => [
        //         ['2206211625251617', '橘酒子弹头11', '口红唇釉', "Benediktiner/百帝王", '0'],
        //         ['2205111130379904', '奶昔杯-121', '腮红', "sulwhasoo/雪花秀", '121'],
        //         ['2205111130378569', '奶昔杯-11', '腮红', "sulwhasoo/雪花秀1111", '12'],
        //     ],
        // ];
        if (!isset($body['isUploadFile']) || empty($body['isUploadFile'])) {
            return Normal::returnCode(Normal::WS_ERROR, '需上传文件');
        }
        if (!isset($body['fileUrl']) || empty($body['fileUrl'])) {
            return Normal::returnCode(Normal::WS_ERROR, '上传到oss的文件链接为空');
        }
        if (!isset($body['upLoadData']) || empty($body['upLoadData'])) {
            return Normal::returnCode(Normal::WS_ERROR, '上传的文件数据为空');
        }
        $originFileUrl  = $body['fileUrl'];
        $pathInfo       = pathinfo($originFileUrl);
        $originFileName = $pathInfo['filename'] ?? $pathInfo['basename'];
        $list           = $body['upLoadData'];
        $managerInfo    = $this->managerInfo($manager_id);
        //去除空行数据
        foreach ($list as $key => $item) {
            $checkCol = array_filter($item);
            if (empty($checkCol) || empty(reset($item))) {
                unset($list[$key]);
            }
        }
        $skuList                 = array_filter(array_column($list, 0));
        $distributor_level       = DistributorLevel::where('cid', $cid)->orderBy('level', 'asc')->orderBy('id', 'asc')->select(['level', 'name'])->get()->toArray();
        $distributor_level_index = $distributor_level ? array_column($distributor_level, 'name', 'level') : [];
        $fields                  = [
            'id', 'medicinal', 'price_recommend', 'is_trade', 'price_recommend_vip', 'price_store', 'base_spec', 'tax_free',
            'tax_rate', 'high_tax_rate', 'is_bonded', 'high_price', 'price_cost'
        ];
        $allGoods                = Goods::whereIn('skucode', $skuList)->where('cid', $cid)->select($fields)->get()->toArray();
        $allGoodsBySku           = array_column($allGoods, null, 'skucode');
        $goods_ids               = array_column($allGoods, 'id');
        $goodsSpec               = GoodsSpecPrice::whereIn('goods_id', $goods_ids)->orderBy('spec_num', 'asc')->get()->toArray();
        $specBygid               = [];
        if ($goodsSpec) {
            foreach ($goodsSpec as $spec) {
                $specBygid[$spec['goods_id']][] = $spec;
            }
        }
        if ($server) {
            $send = Normal::returnCode(Normal::WS_START, "进行中", [
                'percent' => 5,
            ]);
            $server->push($fd, json_encode($send, JSON_UNESCAPED_UNICODE));
        }
        $errorData = [];
        $saveData  = [];
        $timeStp   = time();
        foreach ($list as $v) {
            $skuCode = $v[0];
            if (!isset($allGoodsBySku[$skuCode])) {
                array_push($v, '自编码对应商品不存在');
                $errorData[] = $v;
                continue;
            }
            $res1 = $this->regex($v[1], '/^[1-9]+(,[1-9]+)*$/');
            if (!$res1) {
                array_push($v, '规格数量设置错误 多个规格间英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            $res2 = $this->regex($v[2], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
            if (!$res2) {
                array_push($v, '下游结算价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            $res3 = $this->regex($v[3], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
            if (!$res3) {
                array_push($v, '推荐会员价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            $res4 = $this->regex($v[4], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
            if (!$res4) {
                array_push($v, '推荐零售价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            if (is_string($v[5]) || !is_numeric($v[5])) {
                // $v[5] = false;
                $v[5] = [];
            } else {
                $res5 = $this->regex($v[5], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
                if (!$res5) {
                    array_push($v, '市场价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                    $errorData[] = $v;
                    continue;
                }
            }
            $res6 = $this->regex($v[6], '/^(\d+(\.\d{0,2}+)?)(,\d+(\.\d{0,2}+)?)*$/');
            if (!$res6) {
                array_push($v, '成本价设置错误 价格保留小数点后两位 多个价格用英文逗号隔开');
                $errorData[] = $v;
                continue;
            }
            $row                 = $allGoodsBySku[$skuCode];
            $specListOld         = $specBygid[$row['id']] ?? [];
            $specListOld         = collect($specListOld)->sortBy('spec_num')->toArray();
            $specListOld         = array_column($specListOld, null, 'spec_num');
            $specList            = explode(',', $v[1]);
            $price_store         = explode(',', $v[2]);
            $price_recommend_vip = explode(',', $v[3]);
            $price_recommend     = explode(',', $v[4]);
            $price_market        = explode(',', $v[5]);
            $price_cost          = explode(',', $v[6]);
            $priceCount          = count($specList);
            if (count($price_store) == 1 || count($price_recommend_vip) == 1 || count($price_recommend) == 1) {
                $priceCount = 1;
            }
            if($priceCount==1){
                if($price_store[0]<$price_cost[0] && $row['medicinal']==0){
                    array_push($v, '成本价不能大于结算价');
                    $errorData[] = $v;
                    continue;
                }
                if($price_store[0]>$price_recommend_vip[0]){
                    array_push($v, '结算价不能大于推荐价格');
                    $errorData[] = $v;
                    continue;
                }
                if($price_recommend[0]<$price_recommend_vip[0]){
                    array_push($v, '推荐零售价不能小于推荐会员价');
                    $errorData[] = $v;
                    continue;
                }
                if(isset($price_market[0]) &&$price_market[0]<$price_recommend_vip[0]){
                    array_push($v, '市场价不能低于推荐会员价');
                    $errorData[] = $v;
                    continue;
                }
                if(isset($price_market[0]) &&$price_market[0]<$price_recommend[0]){
                    array_push($v, '市场价不能低于推荐零售价');
                    $errorData[] = $v;
                    continue;
                }
                if($row['is_trade']==0){
                    foreach ($specListOld as $key=>$value){
                        if(isset($price_market[0])){
                            $specListOld[$key]['price_market']=$price_market[0]/$specList[0]*$value['spec_num'];
                        }
                        $specListOld[$key]['price_store']=$price_store[0]/$specList[0]*$value['spec_num'];
                        if($row['medicinal']<>2){
                            $specListOld[$key]['price_recommend']=$price_recommend[0]/$specList[0]*$value['spec_num'];
                            $specListOld[$key]['price_recommend_vip']=$price_recommend_vip[0]/$specList[0]*$value['spec_num'];
                        }
                    }
                }else{
                    if($row['medicinal']==1){
                        if($price_recommend_vip[0]<$row['price_recommend'] || $price_store[0]<$row['price_recommend_vip']){
                            array_push($v, '限价商品零售价不能低于推荐价格');
                            $errorData[] = $v;
                            continue;
                        }
                    }
                }
                //等级分销商结算价判断
                $i = 1;
                $distributorFlag = true;
                $distributorMsg = '';
                foreach ($distributor_level_index as $key=>$val){
                    if(!is_array($v[8+$i])){
                        $v[8+$i]=explode(',',$v[8+$i]);
                    }
                    if($v[8+$i][0] < $price_cost[0] && $row['medicinal']==0){
                        $distributorMsg = $val.'的分销价格不能低于成本价';
                        $distributorFlag = false;
                        break;
                    }
                    if($v[8+$i][0] > $price_recommend_vip[0]){
                        $distributorMsg = $val.'的分销价格不能大于推荐会员价';
                        $distributorFlag = false;
                        break;
                    }
                    if($v[8+$i][0] > $price_recommend[0]){
                        $distributorMsg = $val.'的分销价格不能大于推荐零售价';
                        $distributorFlag = false;
                        break;
                    }
                    $i++;
                }
                if($distributorFlag === false && !empty($distributorMsg)){
                    array_push($v, $distributorMsg);
                    $errorData[] = $v;
                    continue;
                }
            }else{
                if($row['is_trade']==0){
                    if(count($specList) <> count($specListOld)){
                        array_push($v, '规格数量不能修改');
                        $errorData[] = $v;
                        continue;
                    }
                }
                if(count($specList) <> count($price_store)){
                    array_push($v, '规格数量与下游结算价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                if(count($specList) <> count($price_market)){
                    array_push($v, '规格数量与市场价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                if(count($specList) <> count($price_recommend_vip)){
                    array_push($v, '规格数量与推荐会员价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                if(count($specList) <> count($price_recommend)){
                    array_push($v, '规格数量与推荐零售价数量不相等');
                    $errorData[] = $v;
                    continue;
                }
                // if(count($specList) <> count($price_market)){
                //     $v[]='规格数量与市场价数量不相等';
                //     $out[]=$v;
                //     continue;
                // }
                if(count($specList) <> count($price_cost)){
                    array_push($v, '规格数量与成本价数量不相等');
                    $errorData[] = $v;
                    continue;
                }

                foreach ($specList as $spec =>$spec_num){
                    if(!empty($code) && $price_store[$spec]<$price_cost[$spec] && $code['medicinal']==0){
                        $msg ='成本价不能大于结算价';
                        $f = false;
                    }
                    if(!empty($code) && $price_store[$spec]>$price_recommend_vip[$spec]){
                        $msg ='结算价不能大于推荐价格';
                        $f = false;
                    }
                    if(!empty($code) &&$price_recommend[$spec]<$price_recommend_vip[$spec]){
                        $msg = '推荐零售价不能小于推荐会员价';
                        $f = false;
                    }
                    if(!empty($code) && isset($price_market[$spec]) &&$price_recommend[$spec]>$price_market[$spec]){
                        $msg = '推荐零售价不能大于市场价';
                        $f = false;
                    }
                    if(!empty($code) && isset($price_market[$spec]) &&$price_recommend_vip[$spec]>$price_market[$spec]){
                        $msg = '推荐会员价不能大于市场价';
                        $f = false;
                    }
                    if($code['is_trade']==0){
                        if( !empty($code) && $code['medicinal']==1){
                            if($price_recommend_vip[$spec]<$specListOld[$spec_num]['price_recommend'] || $price_store[$spec]<$specListOld[$spec_num]['price_recommend_vip']){
                                $msg = '限价商品零售价不能低于推荐价格';
                                $f = false;
                            }
                        }
                        if(isset($price_market[$spec])){
                            $specListOld[$spec_num]['price_market']=$price_market[$spec];
                        }
                        $specListOld[$spec_num]['price_store']=$price_store[$spec];
                        if($code['medicinal']<>2){
                            $specListOld[$spec_num]['price_recommend']=$price_recommend[$spec];
                            $specListOld[$spec_num]['price_recommend_vip']=$price_recommend_vip[$spec];
                        }
                    }else{
                        if( !empty($code) && $code['medicinal']==1){
                            if($price_recommend_vip[$spec]<$code['price_recommend'] || $price_store[$spec]<$code['price_recommend_vip']){
                                $msg = '限价商品零售价不能低于推荐价格';
                                $f = false;
                            }
                        }
                    }
                    //等级分销商结算价判断
                    $i = 1;
                    foreach ($distributor_level_index as $key=>$val){
                        if(!is_array($v[8+$i])){
                            $v[8+$i]=explode(',',$v[8+$i]);
                        }
                        if(!empty($v[8+$i][$spec])){ //设置了分销商价格
                            if($v[8+$i][$spec] < $price_cost[$spec] && $code['medicinal']==0){
                                $msg = $val.'的分销价格不能低于成本价';
                                $f = false;
                            }
                            if($v[8+$i][$spec] > $price_recommend_vip[$spec]){
                                $msg = $val.'的分销价格不能大于推荐会员价';
                                $f = false;
                            }
                            if($v[8+$i][$spec] > $price_recommend[$spec]){
                                $msg = $val.'的分销价格不能大于推荐零售价';
                                $f = false;
                            }
                        }else{
                            $v[8+$i][$spec] = $price_store[$spec];
                        }
                        $i++;
                    }
                }
            }


        }

    }

    /**
     * 组装批量更新的SQL 语句
     * @param [type] $upData
     * @return array
     * @author huj
     * @DateTime 2022-04-01 09:54:44
     */
    public function mergeSql($upData) {
        //需要更新的字段
        $updateSqlColumns = [
            'name',
            'class_id',
            'brand_id',
            'md',
            'show_order'
        ];
        $when             = [];
        foreach ($upData as $v1) {
            foreach ($updateSqlColumns as $column) {
                $then            = $v1[$column];
                $when[$column][] = "WHEN {$v1['id']} THEN '{$then}'";
            }
        }
        $updateSql = [];
        foreach ($updateSqlColumns as $column) {
            $updateSql[] = "{$column} = CASE id " . (implode(" ", $when[$column])) . " END";
        }
        return [
            'ids'       => array_column($upData, 'id'),
            'updateSql' => $updateSql,
        ];
    }

    //excel头部
    public function getColumns($distributorLevel) {
        $excelTitle = ['sku', '规格数量', '下游结算价', '推荐会员价', '推荐零售价', '市场价(非必填)', '成本价', '名称', '国际编码'];
        foreach ($distributorLevel as $v) {
            $excelTitle[] = $v;
        }
        return $excelTitle;
    }

    /**
     * 获取后台操作人员信息
     */
    public function managerInfo($manager_id) {
        return ManagerChannel::instance()->info(['id' => $manager_id]);
    }

    /**
     * 使用正则验证数据
     * @access public
     * @param mixed $value 字段值
     * @param mixed $rule 验证规则 正则规则或者预定义正则名
     * @return bool
     */
    protected function regex($value, $rule) {
        return is_scalar($value) && 1 === preg_match($rule, (string)$value);
    }

}